
package com.joolun.cloud.mall.admin.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.joolun.cloud.common.core.constant.SecurityConstants;
import com.joolun.cloud.common.data.tenant.TenantContextHolder;
import com.joolun.cloud.mall.admin.mapper.*;
import com.joolun.cloud.mall.admin.service.*;
import com.joolun.cloud.mall.common.config.MallConfigProperties;
import com.joolun.cloud.mall.common.constant.MallConstants;
import com.joolun.cloud.mall.common.entity.*;
import com.joolun.cloud.mall.common.enums.OrderLogisticsEnum;
import com.joolun.cloud.mall.common.enums.OrderInfoEnum;
import com.joolun.cloud.mall.common.feign.FeignWxTemplateMsgService;
import com.joolun.cloud.mall.common.util.Kuaidi100Utils;
import com.joolun.cloud.weixin.common.constant.ConfigConstant;
import com.joolun.cloud.weixin.common.dto.WxTemplateMsgSendDTO;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * 商城订单
 *
 * @author www.joolun.com
 * @date 2019-09-10 15:21:22
 */
@Slf4j
@Service
@AllArgsConstructor
public class OrderInfoServiceImpl extends ServiceImpl<OrderInfoMapper, OrderInfo> implements OrderInfoService {

	private final OrderItemService orderItemService;
	private final OrderLogisticsService orderLogisticsService;
	private final RedisTemplate<String, String> redisTemplate;
	private final MallConfigProperties mallConfigProperties;
	private final FeignWxTemplateMsgService feignWxTemplateMsgService;

	@Override
	@Transactional(rollbackFor = Exception.class)
	public boolean updateById(OrderInfo entity) {
		if(StrUtil.isNotBlank(entity.getLogistics()) && StrUtil.isNotBlank(entity.getLogisticsNo())){//发货。更新快递单号
			entity.setDeliveryTime(LocalDateTime.now());
			OrderLogistics orderLogistics = orderLogisticsService.getOne(Wrappers.<OrderLogistics>lambdaQuery()
					.eq(OrderLogistics::getId,entity.getLogisticsId()));
			//第一次发货调起收到倒计时
			boolean sendRedis = false;
			if(StrUtil.isBlank(orderLogistics.getLogistics()) && StrUtil.isBlank(orderLogistics.getLogisticsNo())){
				sendRedis = true;
			}
			orderLogistics.setLogistics(entity.getLogistics());
			orderLogistics.setLogisticsNo(entity.getLogisticsNo());
			orderLogistics.setStatus(OrderLogisticsEnum.STATUS_1.getValue());
			mallConfigProperties.getLogistics().forEach(logistics -> {
				if(StrUtil.equals(logistics.getCode(), entity.getLogistics())){
					orderLogistics.setLogisticsDesc(logistics.getName());
				}
			});
			orderLogisticsService.updateById(orderLogistics);
			//订阅快递100
			String key = mallConfigProperties.getLogisticsKey();					//企业授权key
			String company = entity.getLogistics();			//快递公司编码
			String number = entity.getLogisticsNo();	//快递单号
			String phone = orderLogistics.getTelNum();					//手机号
			String callbackurl = StrUtil.format("{}{}{}", mallConfigProperties.getNotifyHost(),
					"/mallapi/orderinfo/notify-logisticsr?tenantId="+orderLogistics.getTenantId()+"&logisticsId=",orderLogistics.getId());//回调地址
			String from = "";					//出发地城市
			String to = "";						//目的地城市
			String salt = "";					//加密串
			int resultv2 = 1;					//行政区域解析
			int autoCom = 0;					//单号智能识别
			int interCom = 0;					//开启国际版
			String departureCountry = "";		//出发国
			String departureCom = "";			//出发国快递公司编码
			String destinationCountry = "";		//目的国
			String destinationCom = "";			//目的国快递公司编码

			Kuaidi100Utils kuaidi100Utils = new Kuaidi100Utils(key);
			String result = kuaidi100Utils.subscribeData(company, number, from, to, callbackurl, salt, resultv2, autoCom, interCom, departureCountry, departureCom, destinationCountry, destinationCom, phone);
			JSONObject jSONObject = JSONUtil.parseObj(result);
			if(!(Boolean)jSONObject.get("result")){
				log.error("快递订阅失败：returnCode：{}；message：{}",jSONObject.get("returnCode"),jSONObject.get("message"));
				throw new RuntimeException(String.valueOf(jSONObject.get("message")));
			}
			if(sendRedis){
				//加入redis，7天后自动确认收货
				String keyRedis = String.valueOf(StrUtil.format("{}{}:{}",MallConstants.REDIS_ORDER_KEY_STATUS_2, TenantContextHolder.getTenantId(),entity.getId()));
				redisTemplate.opsForValue().set(keyRedis, entity.getOrderNo() , MallConstants.ORDER_TIME_OUT_2, TimeUnit.DAYS);//设置过期时间
			}
			//发送微信订阅、模板消息
			try {
				OrderInfo orderInfo = baseMapper.selectById(entity.getId());
				orderInfo.setDeliveryTime(entity.getDeliveryTime());
				WxTemplateMsgSendDTO wxTemplateMsgSendDTO = new WxTemplateMsgSendDTO();
				wxTemplateMsgSendDTO.setMallUserId(orderInfo.getUserId());
				wxTemplateMsgSendDTO.setUseType(ConfigConstant.WX_TMP_USE_TYPE_3);
				wxTemplateMsgSendDTO.setPage("pages/order/order-detail/index?id="+orderInfo.getId());
				Map<String, Object> data = new HashMap();
				Map<String, Object> map = BeanUtil.beanToMap(orderInfo);
				for(String mapKey: map.keySet()){
					data.put("order." + mapKey, map.get(mapKey));
				}
				Map<String, Object> map2 = BeanUtil.beanToMap(orderLogistics);
				for(String mapKey: map2.keySet()){
					data.put("orderLogistics." + mapKey, map2.get(mapKey));
				}
				wxTemplateMsgSendDTO.setData(data);
				feignWxTemplateMsgService.sendTemplateMsgMa(wxTemplateMsgSendDTO, SecurityConstants.FROM_IN);
				feignWxTemplateMsgService.sendTemplateMsgMp(wxTemplateMsgSendDTO, SecurityConstants.FROM_IN);
			}catch (Exception e){
				log.error("发送微信订阅、模板消息出错："+e.getMessage(), e);
			}
		}
		return super.updateById(entity);
	}

	@Override
	public IPage<OrderInfo> page1(IPage<OrderInfo> page, Wrapper<OrderInfo> queryWrapper) {
		return baseMapper.selectPage1(page,queryWrapper.getEntity());
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void orderReceive(OrderInfo orderInfo) {
		orderInfo.setStatus(OrderInfoEnum.STATUS_3.getValue());
		orderInfo.setAppraisesStatus(MallConstants.APPRAISES_STATUS_0);
		orderInfo.setReceiverTime(LocalDateTime.now());
		baseMapper.updateById(orderInfo);
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public boolean removeById(Serializable id) {
		orderItemService.remove(Wrappers.<OrderItem>lambdaQuery()
				.eq(OrderItem::getOrderId,id));//删除订单详情
		return super.removeById(id);
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void editPrice(OrderItem orderItem) {
		BigDecimal editPrice = orderItem.getPaymentPrice();
		orderItem = orderItemService.getById(orderItem.getId());
		BigDecimal oldPrice = orderItem.getPaymentPrice();
		orderItem.setPaymentPrice(editPrice);
		OrderInfo orderInfo = baseMapper.selectById(orderItem.getOrderId());
		orderInfo.setPaymentPrice(orderInfo.getPaymentPrice().add(editPrice.subtract(oldPrice)));
		orderItemService.updateById(orderItem);
		orderInfo.setOrderNo(IdUtil.getSnowflake(0,0).nextIdStr());
		baseMapper.updateById(orderInfo);
	}

	@Override
	public BigDecimal sumPaymentPrice(OrderInfo orderInfo) {
		return baseMapper.sumPaymentPrice(orderInfo);
	}

}
